﻿using System;
using System.Collections.Generic;
using System.Linq;
using Quail.Helpers;
using QuailServices.QuailDataServiceReference;

namespace Quail.DbLogger.Task
{
    /// <summary>
    /// Inserts a row into Quail.TestRun
    /// </summary>
    public class InsertTestRun : QuailDbLoggerEntry
    {
        private static readonly Dictionary<string, int?> TestRunLibraryIds = new Dictionary<string, int?>();

        /// <summary>
        /// Initializes a new instance of the <see cref="InsertTestRun"/> class.
        /// </summary>
        /// <param name="testname">The test name.</param>
        /// <param name="environment">The environment (eg: QAS/QAP/etc)</param>
        /// <param name="library">The name of the test library (eg: alltests.dll)</param>
        /// <param name="classname">The classname of the test method (GetType().ToString())</param>
        /// <param name="callback">the callback method</param>
        /// <param name="startDate">Time the test run started</param>
        public InsertTestRun(string testname, string environment, string library, string classname, InsertTestRunComplete callback, DateTime startDate)
        {
            RunStartDate = startDate;
            TestName = testname;
            Environment = environment;
            Library = library;
            ClassName = classname;

            OnInsertTestRunComplete += callback;
        }

        /// <summary>
        /// Callback method for when the insert test run is complete
        /// </summary>
        /// <param name="testrunrunid">the new testrunid</param>
        public delegate void InsertTestRunComplete(int testrunrunid);

        /// <summary>
        /// Called when the store is complete
        /// </summary>
        public event InsertTestRunComplete OnInsertTestRunComplete;

        private string TestName { get; set; }

        private string Environment { get; set; }

        private string Library { get; set; }

        private string ClassName { get; set; }

        private DateTime RunStartDate { get; set; }
        /// <summary>
        /// Starts a new test run
        /// </summary>
        /// <param name="dataContext">the context to use</param>
        public override void Store(QuailServices.QuailDataServiceReference.QuailDataServiceClient dataContext)
        {
            var testrunid = dataContext.StartTestRun(TestName, Environment, Library, (int)LogStatus.Pending, ClassName, RunStartDate, GetTestLibraryRunId(dataContext));

            if (OnInsertTestRunComplete != null)
                OnInsertTestRunComplete(testrunid);
        }

        /// <summary>
        /// Returns a string representation of the entry for logging purposes
        /// </summary>
        /// <returns>A log string</returns>
        public override string GetLogDetail()
        {
            return string.Format("InsertTestRun({0},{1},{2},{3},{4},{5},...)", TestName, Environment, Library,
                                 LogStatus.Pending, ClassName, RunStartDate);
        }

        private int? GetTestLibraryRunId(QuailDataServiceClient dataContext)
        {
            int? result;

            lock (TestRunLibraryIds)
            {
                if (!TestRunLibraryIds.TryGetValue(Library, out result))
                {
                    try
                    {
                        result = dataContext.StartTestLibraryRun(Environment, Library, RunStartDate, System.Environment.MachineName);
                    }
                    catch
                    {
                        // ignore any exceptions
                    }

                    TestRunLibraryIds[Library] = result;
                }
            }

            return result;
        }
    }
}
